package com.shiguiwu.springmybatis.spring.aop.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 *
 * 1,jdk中的Proxy只能为接口生成代理类，如果你想给某个类创建代理类，那么Proxy是无能为力的，此时需要我们用到下面要说的cglib了。
 * 2,Proxy类中提供的几个常用的静态方法大家需要掌握
 * 3,通过Proxy创建代理对象，当调用代理对象任意方法时候，会被InvocationHandler接口中的invoke方法进行处理，这个接口内容是关键
 * @description: 耗时统计，任意方法,任意类
 * @author: stone
 * @date: Created by 2021/3/15 10:04
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.spring.aop.proxy
 */
public class UseTimeInvocationHandler implements InvocationHandler {

    private Object target;

    public UseTimeInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long starTime = System.nanoTime();
        Object result = method.invoke(this.target, args);//@1
        long endTime = System.nanoTime(); //this.target.getClass()  (endTime - starTime)
        long use = endTime - starTime;
        System.out.println(String.format("执行%s的%s的方法，耗时为%s",this.target.getClass() ,method.getName(),use));
        return result;
    }

    public static <T> T createProxy(Object target, Class<T> targetInterface) {
        //判断是否是接口
        if (!targetInterface.isInterface()) {
            throw new IllegalStateException("targetInterface必须是接口类型!");
        }
        //判断是否是实现该接口
        else if (!targetInterface.isAssignableFrom(target.getClass())) {
            throw new IllegalStateException("target必须是targetInterface接口的实现类!");
        }
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new UseTimeInvocationHandler(target));
    }
}
